﻿using System;
using System.IO;

namespace SeleniumToolkit.Util
{
    /// <summary>
    /// Concatenates files together (for user extensions)
    /// </summary>
    public class FileAppender : IDisposable
    {
        #region Constructor / Finalizer
        /// <summary>
        /// Default Constructor
        /// </summary>
        /// <param name="targetPath">Full filepath to file</param>
        /// <param name="pattern">file search pattern for directories</param>
        public FileAppender(string targetPath, string pattern)
        {
            _writer = new StreamWriter(targetPath);
            _pattern = pattern;
        }

        /// <summary>
        /// Finalizer
        /// </summary>
        ~FileAppender()
        {
            Dispose(false);
        } 
        #endregion

        /// <summary>
        /// Append a file to the output stream
        /// </summary>
        /// <param name="file">file or directory to append</param>
        public void Append(string file)
        {
            if (!Path.IsPathRooted(file))
            {
                string applicationFile = Path.Combine(Environment.CurrentDirectory, file);
                if (!File.Exists(applicationFile))
                {
                    throw new FileNotFoundException("Could not locate the file", applicationFile);
                }
                file = applicationFile;
            }

            if (Path.HasExtension(file))
            {
                AppendFile(file);
            }
            else
            {
                AppendDirectory(file);
            }
        }

        private void AppendDirectory(string folder)
        {
            if (Directory.Exists(folder))
            {
                string[] files = Directory.GetFiles(folder, _pattern);
                foreach (string file in files)
                {
                    AppendFile(file);
                }
            }
        }

        private void AppendFile(string file)
        {
            if (File.Exists(file))
            {
                WriteHeader(file);
                WriteContent(file);
            }
            else
            {
                string message = String.Format("Could not locate file \"{0}\"", file);
                throw new FileNotFoundException(message, file);
            }
        }

        private void WriteContent(string file)
        {
            string[] lines = File.ReadAllLines(file);
            foreach (string line in lines)
                _writer.WriteLine(line);
        }

        private void WriteHeader(string file)
        {
            string header = String.Format("// {0}", file);
            _writer.WriteLine(header);
        }

        #region IDisposable Members

        /// <summary>
        /// Dispose the File
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
        }

        /// <summary>
        /// Dispose pattern (clean up managed resources)
        /// </summary>
        /// <param name="disposing"></param>
        protected void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    GC.SuppressFinalize(this);
                }

                _writer.Flush();
                _writer.Dispose();
                _disposed = true;
            }
        }

        #endregion


        private readonly StreamWriter _writer;
        private readonly string _pattern;
        private bool _disposed;
    }
}
